package edu.cque.jt.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author Hua
 * @create 2022-07-15 23:54
 * 定义服务消费端Controller,在这个Controller对象的方法中实现对远端服务sca-provider的调用
 */
@RestController
public class ConsumerController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;//RibbonLoadBalancerClient

    @Autowired
    private RestTemplate loadBalancedRestTemplate;

    /**
     * 基于此对象实现远端服务的调用
     * <p>
     * 先通过类型来注入,如果有多个相同类型,则通过变量 名称来注入,也可以    @Qualifier("")来手动指定名字
     */
    @Autowired
    @Qualifier("restTemplate324")
    private RestTemplate restTemplate;

    @Value("${spring.application.name}")
    private String appName;

    /**
     * 在此方法中通过一个RestTemplate对象调用远端sca-provider中的服务
     *
     * @return
     */
    @GetMapping("/consumer/doRestEcho01")
    public String doRestEcho01() {

        //1. 定义要调用的远端服务的url
        String url = "http://localhost:8081/provider/echo/" + appName;
        //2. 基于restTemplate对象中的相关方法进行服务调用
        return restTemplate.getForObject(url, String.class);
    }

    /*
        目标: 在doRestEcho01的基础上实现负载均衡
     */
    @GetMapping("/consumer/doRestEcho02")
    public String doRestEcho02() {
        //1. 获取provider服务实例  //sca-provider为nacos中的服务名
        ServiceInstance choose = loadBalancerClient.choose("sca-provider");
        //2. 定义要调用的远端服务的url
        String url = String.format("http://%s:%s/provider/echo/%s", choose.getHost(), choose.getPort(), appName);
        System.out.println("url = " + url);
        //3. 基于restTemplate对象中的相关方法进行服务调用
        return restTemplate.getForObject(url, String.class);
    }

    /*
        目标: 在doRestEcho02基础上代码实现简化操作
        简化: 基于loadBalancerClient获取服务实例信息的过程
        如何简化: 底层为RestTemplate对象注入拦截器,在底层拦截器中实现服务实例的获取.
        如何为RestTemplate注入拦截器? 在进行依赖注入的时候,添加 @LoadBalanced
     */
    @GetMapping("/consumer/doRestEcho03")
    public String doRestEcho03() {
        String url = String.format("http://%s/provider/echo/%s", "sca-provider", appName);
        //向服务提供方发起http请求,获取响应数据
        return loadBalancedRestTemplate.getForObject(
                url,//要请求的服务的地址
                String.class);//String.class为请求服务的响应结果类型
    }

}
